#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "params.h"
#include "types.h"
#include "defs.h"
#include "jitcc.h"
#include "parser.h"
#include "runtime.h"
#include "x86_64def.h"

#define MAX_TBSZ 0x1000 // TB指令缓冲区/块大小最大4KB
struct runtime * rtscratch;
char tbbuf[MAX_TBSZ];
uint tptr;
union imm8 i8scratch;
union imm16 i16scratch;
union imm32 i32scratch;
union imm64 i64scratch;

uint rdscratch;
uint rs1scratch;
uint rs2scratch;
uint rdtag;
uint rs1tag;
uint rs2tag;
uint rexscratch;

#define AX_TAG 0
#define CX_TAG 0
#define DX_TAG 0
#define BX_TAG 0
#define BP_TAG 0
#define SP_TAG 0
#define DI_TAG 0
#define SI_TAG 0
#define R8_TAG 1
#define R9_TAG 1
#define R10_TAG 1
#define R11_TAG 1
#define R12_TAG 1
#define R13_TAG 1
#define R14_TAG 1
#define R15_TAG 1

#define NONE_TAG 0

#define IMM8 (i8scratch)
#define IMM16 (i16scratch)
#define IMM32 (i32scratch)
#define IMM64 (i64scratch)

/* P=Prefix R=Rex O=Opcode M=ModR/M I[8,16,32,64]=imm */

#define EMIT_O(opcode) {tbbuf[tptr++] = opcode;}
#define EMIT_RO(rex,opcode) {tbbuf[tptr++]=rex;\
tbbuf[tptr++]=opcode;}
#define EMIT_OM(opcode,modrm) {        \
    tbbuf[tptr++]=opcode;               \
    tbbuf[tptr++]=modrm;                \
}
#define EMIT_ROM(rex,opcode,modrm) {   \
    tbbuf[tptr++]=rex;                  \
    tbbuf[tptr++]=opcode;               \
    tbbuf[tptr++]=modrm;                \
}
#define EMIT_OMI8(opcode,modrm,imm) {  \
    IMM8.num = imm;                     \
    tbbuf[tptr++]=opcode;               \
    tbbuf[tptr++]=modrm;                \
    tbbuf[tptr++]=IMM8.byte[0];         \
}
#define EMIT_ROMI8(rex,opcode,modrm,imm){\
    IMM8.num = imm;                     \
    tbbuf[tptr++]=rex;                  \
    tbbuf[tptr++]=opcode;               \
    tbbuf[tptr++]=modrm;                \
    tbbuf[tptr++]=IMM8.byte[0];         \
}
#define EMIT_OI8(opcode,imm) {          \
    IMM8.num = imm;                     \
    tbbuf[tptr++]=opcode;               \
    tbbuf[tptr++]=IMM8.byte[0];         \
}
#define EMIT_ROI8(rex,opcode,imm) {     \
    IMM8.num = imm;                     \
    tbbuf[tptr++]=rex;                  \
    tbbuf[tptr++]=opcode;               \
    tbbuf[tptr++]=IMM8.byte[0];         \
}
#define EMIT_OMI32(opcode,imm) {       \
    IMM32.num = imm;                    \
    tbbuf[tptr++]=opcode;               \
    memcpy(tbbuf+tptr,IMM32.byte,4);    \
    tptr+=4;                            \
}
#define EMIT_ROMI32(rex,opcode,modrm,imm) {  \
    IMM32.num = imm;                    \
    tbbuf[tptr++]=rex;                  \
    tbbuf[tptr++]=modrm;                \
    tbbuf[tptr++]=opcode;               \
    memcpy(tbbuf+tptr,IMM32.byte,4);    \
    tptr+=4;                            \
}
#define EMIT_ROI64(rex,opcode,imm) {    \
    IMM64.num = imm;                    \
    tbbuf[tptr++]=rex;                  \
    tbbuf[tptr++]=opcode;               \
    memcpy(tbbuf+tptr,IMM64.byte,8);    \
    tptr+=8;                            \
}
#define EMIT_POM(prefix,opcode,modrm) { \
    tbbuf[tptr++]=prefix;               \
    tbbuf[tptr++]=opcode;               \
    tbbuf[tptr++]=modrm;                \
}
#define EMIT_RPOM(rex,prefix,opcode,modrm) {\
    tbbuf[tptr++]=rex;               \
    tbbuf[tptr++]=prefix;                  \
    tbbuf[tptr++]=opcode;               \
    tbbuf[tptr++]=modrm;                \
}

#define V (inst->v)
#define issigned(v) (v->type%2 == 1)
// ModRM(mod,r,rm)
// NOTE: REX.B for RM; REX.R for R
uint
x2r_reg (enum reg_nm x) {
    switch (x) {
        case X_A0 : {
            return R_AX;
            break;
        }
        case X_A1 : {
            return R_CX;
            break;
        }
        case X_A2 : {
            return R_DX;
            break;
        }
        case X_A3 : {
            return R_BX;
            break;
        }
        case X_T0 : {
            return R_R8;
            break;
        }
        case X_T1 : {
            return R_R9;
            break;
        }
        case X_T2 : {
            return R_R10;
            break;
        }
        case X_T3 : {
            return R_R11;
            break;
        }
        case X_T4 : {
            return R_R12;
            break;
        }
        case X_T5 : {
            return R_R13;
            break;
        }
        case X_T6 : {
            return R_R14;
            break;
        }
        case X_T7 : {
            return R_R15;
            break;
        }
        default : break;
    }
    return ERROR;
}

uint // 只有r寄存器才会把标签置1
x2r_tag (enum reg_nm x) {
    if (x>=X_A0 && x<=X_A3)
        return 0;
    if (x>=X_T0 && x<=X_T7)
        return 1;
    return ERROR;
}

char // 参数: reg_TAG
gen_rex (uint r_tag, uint rm_tag) {
    if (r_tag == 0 && rm_tag == 0)
        return REX_W;
    if (r_tag == 0 && rm_tag == 1)
        return REX_WB;
    if (r_tag == 1 && rm_tag == 0)
        return REX_WR;
    if (r_tag == 1 && rm_tag == 1)
        return REX_WRB;
    return 0;
}

uint // 变量地址shift
getvaridxshft (enum var_type vt) {
    switch (vt) {
        case VAR_UNDEF:
        case VAR_INVALID:
        case VAR_I8: {
            return 0;
            break;
        }
        case VAR_I16: {
            return 1;
            break;
        }
        case VAR_I32: {
            return 2;
            break;
        }
        case VAR_I64: {
            return 3;
            break;
        }
        case VAR_U8: {
            return 0;
            break;
        }
        case VAR_U16: {
            return 1;
            break;
        }
        case VAR_U32: {
            return 2;
            break;
        }
        case VAR_U64: {
            return 3;
            break;
        }
        case VAR_SPACE: {
            return 3;
            break;
        }
        case VAR_STR: {
            return 3;
            break;
        }
        default : break;
    }
    return 0;
}

#define RD (x2r_reg (inst->r0))
#define RS1 (x2r_reg (inst->r1))
#define RS2 (x2r_reg (inst->r2))
#define RD_TAG (x2r_tag (inst->r0))
#define RS1_TAG (x2r_tag (inst->r1))
#define RS2_TAG (x2r_tag (inst->r2))
#define REX(tag1,tag2) (gen_rex (tag1,tag2))


uint
emit_prologue () {
    EMIT_O(OP_PUSH_BP); // PUSH RBP
    EMIT_ROM(REX_W, OP_MOV_MR, ModRM(MOD_R,R_SP,RM_BP)) // MOV RBP RSP
    EMIT_ROMI8(REX_W, OP_MOV_RM, ModRM(MOD_RM_D8,R_AX,R_DI),0); // MOV RAX, 0[RDI]
    EMIT_ROMI8(REX_W, OP_MOV_RM, ModRM(MOD_RM_D8,R_CX,R_DI),8); // MOV RCX, 8[RDI]
    EMIT_ROMI8(REX_W, OP_MOV_RM, ModRM(MOD_RM_D8,R_DX,R_DI),16); // MOV RDX, 16[RDI]
    EMIT_ROMI8(REX_W, OP_MOV_RM, ModRM(MOD_RM_D8,R_BX,R_DI),24); // MOV RBX, 24[RDI]
    EMIT_ROMI8(REX_WR, OP_MOV_RM, ModRM(MOD_RM_D8,R_R8,R_DI),32); // MOV R8, 32[RDI]
    EMIT_ROMI8(REX_WR, OP_MOV_RM, ModRM(MOD_RM_D8,R_R9,R_DI),40); // MOV R9, 40[RDI]
    EMIT_ROMI8(REX_WR, OP_MOV_RM, ModRM(MOD_RM_D8,R_R10,R_DI),48); // MOV R10, 48[RDI]
    EMIT_ROMI8(REX_WR, OP_MOV_RM, ModRM(MOD_RM_D8,R_R11,R_DI),56); // MOV R11, 56[RDI]
    EMIT_ROMI8(REX_WR, OP_MOV_RM, ModRM(MOD_RM_D8,R_R12,R_DI),64); // MOV R12, 64[RDI]
    EMIT_ROMI8(REX_WR, OP_MOV_RM, ModRM(MOD_RM_D8,R_R13,R_DI),72); // MOV R13, 72[RDI]
    EMIT_ROMI8(REX_WR, OP_MOV_RM, ModRM(MOD_RM_D8,R_R14,R_DI),80); // MOV R14, 80[RDI]
    EMIT_ROMI8(REX_WR, OP_MOV_RM, ModRM(MOD_RM_D8,R_R15,R_DI),88); // MOV R15, 88[RDI]
    return tptr;
}

uint
emit_epilogue () {
    EMIT_ROMI8(REX_W, OP_MOV_MR, ModRM(MOD_RM_D8,R_AX,R_DI),0); // MOV 0[RDI], RAX
    EMIT_ROMI8(REX_W, OP_MOV_MR, ModRM(MOD_RM_D8,R_CX,R_DI),8); // MOV 8[RDI], RCX
    EMIT_ROMI8(REX_W, OP_MOV_MR, ModRM(MOD_RM_D8,R_DX,R_DI),16); // MOV 16[RDI], RDX
    EMIT_ROMI8(REX_W, OP_MOV_MR, ModRM(MOD_RM_D8,R_BX,R_DI),24); // MOV 24[RDI], RBX
    EMIT_ROMI8(REX_WR, OP_MOV_MR, ModRM(MOD_RM_D8,R_R8,R_DI),32); // MOV 32[RDI], R8
    EMIT_ROMI8(REX_WR, OP_MOV_MR, ModRM(MOD_RM_D8,R_R9,R_DI),40); // MOV 40[RDI], R9
    EMIT_ROMI8(REX_WR, OP_MOV_MR, ModRM(MOD_RM_D8,R_R10,R_DI),48); // MOV 48[RDI], R10
    EMIT_ROMI8(REX_WR, OP_MOV_MR, ModRM(MOD_RM_D8,R_R11,R_DI),56); // MOV 56[RDI], R11
    EMIT_ROMI8(REX_WR, OP_MOV_MR, ModRM(MOD_RM_D8,R_R12,R_DI),64); // MOV 64[RDI], R12
    EMIT_ROMI8(REX_WR, OP_MOV_MR, ModRM(MOD_RM_D8,R_R13,R_DI),72); // MOV 72[RDI], R13
    EMIT_ROMI8(REX_WR, OP_MOV_MR, ModRM(MOD_RM_D8,R_R14,R_DI),80); // MOV 80[RDI], R14
    EMIT_ROMI8(REX_WR, OP_MOV_MR, ModRM(MOD_RM_D8,R_R15,R_DI),88); // MOV 88[RDI], R15
    EMIT_O(OP_POP_BP);  // POP RBP
    EMIT_O(OP_RET); // RET
    return tptr;
}

// /* ir转换成x86-64指令 */
// uint // 返回新tptr,错误返回-1
// ir2x86 (struct ins * inst) {

// }

uint
emit_asgn (struct ins * inst) {
    EMIT_ROMI8(REX_W, OP_MOV_MR, ModRM(MOD_RM_D8,R_AX,R_DI),0); // MOV 0[RDI], RAX
    EMIT_ROMI8(REX_W, OP_MOV_MR, ModRM(MOD_RM_D8,R_CX,R_DI),8); // MOV 8[RDI], RCX
    EMIT_ROMI8(REX_W, OP_MOV_MR, ModRM(MOD_RM_D8,R_DX,R_DI),16); // MOV 16[RDI], RDX
    EMIT_ROMI8(REX_W, OP_MOV_MR, ModRM(MOD_RM_D8,R_BX,R_DI),24); // MOV 24[RDI], RBX
    EMIT_ROMI8(REX_WR, OP_MOV_MR, ModRM(MOD_RM_D8,R_R8,R_DI),32); // MOV 32[RDI], R8
    EMIT_ROMI8(REX_WR, OP_MOV_MR, ModRM(MOD_RM_D8,R_R9,R_DI),40); // MOV 40[RDI], R9
    EMIT_ROMI8(REX_WR, OP_MOV_MR, ModRM(MOD_RM_D8,R_R10,R_DI),48); // MOV 48[RDI], R10
    EMIT_ROMI8(REX_WR, OP_MOV_MR, ModRM(MOD_RM_D8,R_R11,R_DI),56); // MOV 56[RDI], R11
    EMIT_ROMI8(REX_WR, OP_MOV_MR, ModRM(MOD_RM_D8,R_R12,R_DI),64); // MOV 64[RDI], R12
    EMIT_ROMI8(REX_WR, OP_MOV_MR, ModRM(MOD_RM_D8,R_R13,R_DI),72); // MOV 72[RDI], R13
    EMIT_ROMI8(REX_WR, OP_MOV_MR, ModRM(MOD_RM_D8,R_R14,R_DI),80); // MOV 80[RDI], R14
    EMIT_ROMI8(REX_WR, OP_MOV_MR, ModRM(MOD_RM_D8,R_R15,R_DI),88); // MOV 88[RDI], R15
    EMIT_O(OP_PUSH_AX);
    EMIT_O(OP_PUSH_DI);
    EMIT_O(OP_PUSH_SI);
    EMIT_O(OP_PUSH_DX);
    EMIT_O(OP_PUSH_CX);
    EMIT_RO(REX_B, OP_PUSH_R8);
    EMIT_RO(REX_B, OP_PUSH_R9);
    EMIT_RO(REX_B, OP_PUSH_R10);
    EMIT_RO(REX_B, OP_PUSH_R11);
    EMIT_ROI64(REX_W, OP_MOVABS, (uint64)inst); // RAX <- inst
    EMIT_ROM(REX_W, OP_MOV_MR, ModRM(MOD_R,R_AX,R_SI)); // MOV RSI, RAX // assignvar第二个参数inst, 第一个参数为最初传进来的regs
    EMIT_ROI64(REX_W, OP_MOVABS, (uint64)assignvar); // RAX <- assignvar
    EMIT_ROM(REX_W, OP_MOV_MR, ModRM(MOD_R,R_AX,R_DX)); // MOV RDX, RAX
    EMIT_OM(OP_CALL_M, ModRM(MOD_R,2,RM_DX)); // CALL RDX
    //EMIT_O(OP_NOP);
    EMIT_RO (REX_B, OP_POP_R11);
    EMIT_RO (REX_B, OP_POP_R10);
    EMIT_RO (REX_B, OP_POP_R9);
    EMIT_RO (REX_B, OP_POP_R8);
    EMIT_O(OP_POP_CX);
    EMIT_O(OP_POP_DX);
    EMIT_O(OP_POP_SI);
    EMIT_O(OP_POP_DI);
    EMIT_O(OP_POP_AX);
    return tptr;
}

uint
emit_ecall (struct ins * inst) {
    (void) inst;
    //EMIT_O(OP_PUSH_AX);
    EMIT_O(OP_PUSH_DI);
    EMIT_O(OP_PUSH_SI);
    EMIT_O(OP_PUSH_DX);
    EMIT_O(OP_PUSH_CX);
    EMIT_RO(REX_B, OP_PUSH_R8);
    EMIT_RO(REX_B, OP_PUSH_R9);
    EMIT_RO(REX_B, OP_PUSH_R10);
    EMIT_RO(REX_B, OP_PUSH_R11);
    // A0=RAX->RDI A1=RCX->RSI A2=RDX->RDX
    // MOVABS RAX, ecall
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R,R_AX,RM_DI)); // MOV RDI, RAX 装入第一个参数
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R,R_CX,RM_SI)); // MOV RSI, RCX 装入第二个参数
    // 第三个参数在RDX
    EMIT_ROI64(REX_W, OP_MOVABS, (uint64)ecall); // RAX <- ecall
    EMIT_OM(OP_CALL_M, ModRM(MOD_R,2,RM_AX)); // CALL RAX 返回值在RAX
    EMIT_O(OP_NOP);
    EMIT_RO (REX_B, OP_POP_R11);
    EMIT_RO (REX_B, OP_POP_R10);
    EMIT_RO (REX_B, OP_POP_R9);
    EMIT_RO (REX_B, OP_POP_R8);
    EMIT_O(OP_POP_CX);
    EMIT_O(OP_POP_DX);
    EMIT_O(OP_POP_SI);
    EMIT_O(OP_POP_DI);
    //EMIT_O(OP_POP_AX);
    return tptr;
}

void
_emit_cast_chv(struct var * v ,enum var_type type) {
    v->type = type;
    return;
}

uint
emit_cast (struct ins * inst) {
    if (!(inst->v->flg & F_VAR_VALID)) return ERROR;
    if (!(inst->v->flg & F_VAR_HEAP) && !(inst->v->flg & F_VAR_STACK)) return ERROR;
    EMIT_O(OP_PUSH_AX); // PUSH RAX
    if ((inst->v->flg & F_VAR_STACK)) {
        EMIT_ROI64 (REX_W, OP_MOVABS, V->stackoff); // movabs rax, stackoff
        EMIT_ROMI8(REX_W, OP_MOV_RM, ModRM(MOD_RM_D8,R_SI,R_DI),96);  // MOV RSI, 96[RDI] => FP
        EMIT_ROM(REX_W, OP_ADD_MR, ModRM(MOD_R,R_SI,RM_AX)); // ADD RAX, RSI 这个地方是栈中首地址
        switch (getvaridxshft(V->type)) {
            case 0: { // #NOTE:0x40:rex,访问sil用
                EMIT_ROM (REX_NEW,OP_MOV_RM8, ModRM(MOD_RM,R_SI,RM_AX)); // MOVB SIL, [RAX]
                break;
            }
            case 1: {
                EMIT_ROM (REX_16, OP_MOV_RM,ModRM(MOD_RM,R_SI,RM_AX)); // MOVW SI, [RAX]
                break;
            }
            case 2: {
                //EMIT_ROM (REX_W,OP_XOR_MR,ModRM(MOD_R,R_SI,RM_SI)); // XOR RSI RSI
                EMIT_OM (OP_MOV_RM,ModRM(MOD_RM,R_SI,RM_AX)); // MOVL ESI, [RAX]
                break;
            }
            case 3: {
                EMIT_ROM (REX_W ,OP_MOV_RM,ModRM(MOD_RM,R_SI,RM_AX)); // MOVQ RSI, [RAX]
                break;
            }
        }
    }
    if ((inst->v->flg & F_VAR_HEAP)) {
        EMIT_ROI64 (REX_W, OP_MOVABS, (uint64)V->heapaddr); // MOVABS RAX, v->heapaddr, 存储指向实际内容的指针
        switch (getvaridxshft(V->type)) {
            case 0: { // #NOTE:0x40:rex,访问sil用
                EMIT_ROM (REX_NEW,OP_MOV_RM8, ModRM(MOD_RM,R_SI,RM_AX)); // MOVB SIL, [RAX]
                break;
            }
            case 1: {
                EMIT_ROM (REX_16, OP_MOV_RM,ModRM(MOD_RM,R_SI,RM_AX)); // MOVW SI, [RAX]
                break;
            }
            case 2: {
                EMIT_OM (OP_MOV_RM,ModRM(MOD_RM,R_SI,RM_AX)); // MOVL ESI, [RAX]
                break;
            }
            case 3: {
                EMIT_ROM (REX_W ,OP_MOV_RM,ModRM(MOD_RM,R_SI,RM_AX)); // MOVQ RSI, [RAX]
                break;
            }
        }
    }
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_RM, R_SI, RM_AX)); // MOV [RAX], RSI
    // 现在变量已更新

    EMIT_O(OP_PUSH_DI);
    EMIT_O(OP_PUSH_SI);
    EMIT_O(OP_PUSH_DX);
    EMIT_O(OP_PUSH_CX);
    EMIT_RO(REX_B, OP_PUSH_R8);
    EMIT_RO(REX_B, OP_PUSH_R9);
    EMIT_RO(REX_B, OP_PUSH_R10);
    EMIT_RO(REX_B, OP_PUSH_R11);
    EMIT_ROI64(REX_W, OP_MOVABS, (uint64)V); // RAX <- V
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R,R_AX,RM_DI)); // MOV RDI, RAX 装入第一个参数
    EMIT_ROI64(REX_W, OP_MOVABS, (uint64)inst->casttype); // RAX <- casttype
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R,R_AX,RM_SI)); // MOV RSI, RAX 装入第二个参数
    EMIT_ROI64(REX_W, OP_MOVABS, (uint64)_emit_cast_chv); // RAX _emit_cast_chv
    EMIT_OM(OP_CALL_M, ModRM(MOD_R,2,RM_AX)); // CALL RAX 返回值在RAX
    EMIT_O(OP_NOP);
    EMIT_RO (REX_B, OP_POP_R11);
    EMIT_RO (REX_B, OP_POP_R10);
    EMIT_RO (REX_B, OP_POP_R9);
    EMIT_RO (REX_B, OP_POP_R8);
    EMIT_O(OP_POP_CX);
    EMIT_O(OP_POP_DX);
    EMIT_O(OP_POP_SI);
    EMIT_O(OP_POP_DI);

    EMIT_O(OP_POP_AX); // POP RAX
    return tptr;
}

uint
emit_li (struct ins * inst) {
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R, R_AX, RM_SI)); //MOV RSI, RAX
    EMIT_ROI64 (REX_W, OP_MOVABS, inst->imm); // MOVABS RAX, imm
    EMIT_ROM (REX(AX_TAG,RD_TAG), OP_MOV_MR, ModRM(MOD_R,R_AX,RD)); // MOV RD, RAX
    if (RD != R_AX)
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R, R_SI, RM_AX)); // MOV RAX, RSI
    return tptr;
}

uint
emit_addi (struct ins * inst) {
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R, R_AX, RM_SI));// MOV RSI, RAX
    EMIT_ROI64 (REX_W, OP_MOVABS, inst->imm); // MOVABS RAX, imm
    EMIT_ROM (REX(RS1_TAG,AX_TAG), OP_ADD_MR, ModRM(MOD_R,RS1,RM_AX)); // ADD RAX, RS1
    EMIT_ROM (REX(AX_TAG,RD_TAG), OP_MOV_MR, ModRM(MOD_R,R_AX,RD)); // MOV RD, RAX
    if (RD != R_AX)
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R,R_SI,RM_AX)) // MOV RAX, RSI
    return tptr;
}

uint
emit_slti (struct ins * inst) {
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R, R_AX, RM_SI));// MOV RSI, RAX
    EMIT_ROI64 (REX_W, OP_MOVABS, inst->imm); // MOVABS RAX, imm
    EMIT_ROMI32 (REX(NONE_TAG,RD_TAG),OP_MOV_MI,ModRM(MOD_R,0,RD),1); // MOV RD, 1
    EMIT_ROM (REX(AX_TAG,RS1_TAG),OP_CMP_MR,ModRM(MOD_R,R_AX,RS1)); // CMP RS1, RAX
    EMIT_OI8 (OP_JL_REL8, 0x3); // JL $+0x3 => MOV RAX RSI
    EMIT_ROM (REX(RD_TAG,RD_TAG),OP_XOR_MR,ModRM(MOD_R,RD,RD)); // XOR RD RD, 指令3B
    if (RD != R_AX)
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R,R_SI,RM_AX)); // MOV RAX RSI
    return tptr;
}

uint
emit_sltiu (struct ins * inst) {
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R, R_AX, RM_SI));// MOV RSI, RAX
    EMIT_ROI64 (REX_W, OP_MOVABS, inst->imm); // MOVABS RAX, imm
    EMIT_ROMI32 (REX(NONE_TAG,RD_TAG),OP_MOV_MI,ModRM(MOD_R,0,RD),1); // MOV RD, 1
    EMIT_ROM (REX(AX_TAG,RS1_TAG),OP_CMP_MR,ModRM(MOD_R,R_AX,RS1)); // CMP RS1, RAX
    EMIT_OI8 (OP_JB_REL8, 0x3); // JB $+0x3 => MOV RAX RSI
    EMIT_ROM (REX(RD_TAG,RD_TAG),OP_OR_MR,ModRM(MOD_R,RD,RD)); // XOR RD RD, 指令3B
    if (RD != R_AX)
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R,R_SI,RM_AX)); // MOV RAX RSI
    return tptr;
}

// 
uint
emit_xori (struct ins * inst) {
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R, R_AX, RM_SI));// MOV RSI, RAX
    EMIT_ROI64 (REX_W, OP_MOVABS, inst->imm); // MOVABS RAX, imm
    EMIT_ROM (REX(RS1_TAG,AX_TAG), OP_XOR_MR, ModRM(MOD_R,RS1,RM_AX)); // XOR RAX, RS1
    EMIT_ROM (REX(AX_TAG,RD_TAG), OP_MOV_MR, ModRM(MOD_R,R_AX,RD)); // MOV RD, RAX
    if (RD != R_AX)
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R,R_SI,RM_AX)) // MOV RAX, RSI
    return tptr;
}

uint
emit_ori (struct ins * inst) {
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R, R_AX, RM_SI));// MOV RSI, RAX
    EMIT_ROI64 (REX_W, OP_MOVABS, inst->imm); // MOVABS RAX, imm
    EMIT_ROM (REX(RS1_TAG,AX_TAG), OP_OR_MR, ModRM(MOD_R,RS1,RM_AX)); // OR RAX, RS1
    EMIT_ROM (REX(AX_TAG,RD_TAG), OP_MOV_MR, ModRM(MOD_R,R_AX,RD)); // MOV RD, RAX
    if (RD != R_AX)
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R,R_SI,RM_AX)) // MOV RAX, RSI
    return tptr;
}

uint
emit_andi (struct ins * inst) {
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R, R_AX, RM_SI));// MOV RSI, RAX
    EMIT_ROI64 (REX_W, OP_MOVABS, inst->imm); // MOVABS RAX, imm
    EMIT_ROM (REX(RS1_TAG,AX_TAG), OP_AND_MR, ModRM(MOD_R,RS1,RM_AX)); // AND RAX, RS1
    EMIT_ROM (REX(AX_TAG,RD_TAG), OP_MOV_MR, ModRM(MOD_R,R_AX,RD)); // MOV RD, RAX
    if (RD != R_AX)
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R,R_SI,RM_AX)) // MOV RAX, RSI
    return tptr;
}

uint
emit_slli (struct ins * inst) {
    EMIT_ROM (REX(RS1_TAG, SI_TAG), OP_MOV_MR, ModRM(MOD_R, RS1, RM_SI)); // MOV RSI, RS1
    EMIT_ROMI8 (REX_W, OP_SHL_MI8, ModRM(MOD_R,6,RM_SI),(char)inst->imm); // SHL RSI, imm8
    EMIT_ROM (REX(SI_TAG,RD_TAG), OP_MOV_MR, ModRM(MOD_R,R_SI,RD)); // MOV RD, RSI
    return tptr;
}

uint
emit_srli (struct ins * inst) {
    EMIT_ROM (REX(RS1_TAG, SI_TAG), OP_MOV_MR, ModRM(MOD_R, RS1, RM_SI)); // MOV RSI, RS1
    EMIT_ROMI8 (REX_W, OP_SHR_MI8, ModRM(MOD_R,5,RM_SI),(char)inst->imm); // SHR RSI, imm8
    EMIT_ROM (REX(SI_TAG,RD_TAG), OP_MOV_MR, ModRM(MOD_R,R_SI,RD)); // MOV RD, RSI
    return tptr;
}

uint
emit_srai (struct ins * inst) {
    EMIT_ROM (REX(RS1_TAG, SI_TAG), OP_MOV_MR, ModRM(MOD_R, RS1, RM_SI)); // MOV RSI, RS1
    EMIT_ROMI8 (REX_W, OP_SAR_MI8, ModRM(MOD_R,7,RM_SI),(char)inst->imm); // SAR RSI, imm8
    EMIT_ROM (REX(SI_TAG,RD_TAG), OP_MOV_MR, ModRM(MOD_R,R_SI,RD)); // MOV RD, RSI
    return tptr;
}

uint
emit_add (struct ins * inst) {
    EMIT_ROM (REX(RS1_TAG, SI_TAG), OP_MOV_MR, ModRM(MOD_R, RS1, RM_SI)); // MOV RSI, RS1
    EMIT_ROM (REX(RS2_TAG,SI_TAG),OP_ADD_MR,ModRM(MOD_R,RS2,RM_SI)); // ADD RSI, RS2
    EMIT_ROM (REX(SI_TAG,RD_TAG), OP_MOV_MR, ModRM(MOD_R,R_SI,RD)); // MOV RD, RSI
    return tptr;
}

uint
emit_sub (struct ins * inst) {
    EMIT_ROM (REX(RS1_TAG, SI_TAG), OP_MOV_MR, ModRM(MOD_R, RS1, RM_SI)); // MOV RSI, RS1
    EMIT_ROM (REX(RS2_TAG,SI_TAG),OP_SUB_MR,ModRM(MOD_R,RS2,RM_SI)); // ADD RSI, RS2
    EMIT_ROM (REX(SI_TAG,RD_TAG), OP_MOV_MR, ModRM(MOD_R,R_SI,RD)); // MOV RD, RSI
    return tptr;
}

uint
emit_sll (struct ins * inst) {
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R,R_CX,RM_SI)); // MOV RSI RCX
    EMIT_ROM (REX(RS2_TAG, CX_TAG), OP_MOV_MR, ModRM (MOD_R, RS2, RM_CX)); // MOV RCX, RS2
    EMIT_ROM (REX(RS1_TAG,RD_TAG), OP_MOV_MR, ModRM(MOD_R,RS1,RD)); // MOV RD RS1
    EMIT_ROM (REX(NONE_TAG,RD_TAG),OP_SHL_MCL, ModRM(MOD_R,6,RD));
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R,RM_SI,R_CX)); // MOV RCX RSI
    return tptr;
}

uint
emit_slt (struct ins * inst) {
    EMIT_ROMI32 (REX(NONE_TAG,RD_TAG),OP_MOV_MI,ModRM(MOD_R,0,RD),1); // MOV RD, 1
    EMIT_ROM (REX(RS2_TAG,RS1_TAG),OP_CMP_MR,ModRM(MOD_R,RS2,RS1)); // CMP RS1, RS2
    EMIT_OI8 (OP_JL_REL8, 0x3); // JL $+0x3 => END
    EMIT_ROM (REX(RD_TAG,RD_TAG),OP_XOR_MR,ModRM(MOD_R,RD,RD)); // XOR RD RD, 指令3B
    return tptr;
}

uint
emit_sltu (struct ins * inst) {
    EMIT_ROMI32 (REX(NONE_TAG,RD_TAG),OP_MOV_MI,ModRM(MOD_R,0,RD),1); // MOV RD, 1
    EMIT_ROM (REX(RS2_TAG,RS1_TAG),OP_CMP_MR,ModRM(MOD_R,RS2,RS1)); // CMP RS1, RS2
    EMIT_OI8 (OP_JB_REL8, 0x3); // JL $+0x3 => END
    EMIT_ROM (REX(RD_TAG,RD_TAG),OP_XOR_MR,ModRM(MOD_R,RD,RD)); // XOR RD RD, 指令3B
    return tptr;
}

uint
emit_xor (struct ins * inst) {
    EMIT_ROM (REX(RS1_TAG, SI_TAG), OP_MOV_MR, ModRM(MOD_R, RS1, RM_SI)); // MOV RSI, RS1
    EMIT_ROM (REX(RS2_TAG,SI_TAG),OP_XOR_MR,ModRM(MOD_R,RS2,RM_SI)); // XOR RSI, RS2
    EMIT_ROM (REX(SI_TAG,RD_TAG), OP_MOV_MR, ModRM(MOD_R,R_SI,RD)); // MOV RD, RSI
    return tptr;
}

uint
emit_srl (struct ins * inst) {
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R,R_CX,RM_SI)); // MOV RSI RCX
    EMIT_ROM (REX(RS2_TAG, CX_TAG), OP_MOV_MR, ModRM (MOD_R, RS2, RM_CX)); // MOV RCX, RS2
    EMIT_ROM (REX(RS1_TAG,RD_TAG), OP_MOV_MR, ModRM(MOD_R,RS1,RD)); // MOV RD RS1
    EMIT_ROM (REX(NONE_TAG,RD_TAG),OP_SHR_MCL, ModRM(MOD_R,5,RD)); // SHR RD, CL
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R,RM_SI,R_CX)); // MOV RCX RSI
    return tptr;
}

uint
emit_sra (struct ins * inst) {
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R,R_CX,RM_SI)); // MOV RSI RCX
    EMIT_ROM (REX(RS2_TAG, CX_TAG), OP_MOV_MR, ModRM (MOD_R, RS2, RM_CX)); // MOV RCX, RS2
    EMIT_ROM (REX(RS1_TAG,RD_TAG), OP_MOV_MR, ModRM(MOD_R,RS1,RD)); // MOV RD RS1
    EMIT_ROM (REX(NONE_TAG,RD_TAG),OP_SAR_MCL, ModRM(MOD_R,7,RD)); // SAR RD, CL
    EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R,RM_SI,R_CX)); // MOV RCX RSI
    return tptr;
}

uint
emit_or (struct ins * inst) {
    EMIT_ROM (REX(RS1_TAG, SI_TAG), OP_MOV_MR, ModRM(MOD_R, RS1, RM_SI)); // MOV RSI, RS1
    EMIT_ROM (REX(RS2_TAG,SI_TAG),OP_OR_MR,ModRM(MOD_R,RS2,RM_SI)); // OR RSI, RS2
    EMIT_ROM (REX(SI_TAG,RD_TAG), OP_MOV_MR, ModRM(MOD_R,R_SI,RD)); // MOV RD, RSI
    return tptr;
}

uint
emit_and (struct ins * inst) {
    EMIT_ROM (REX(RS1_TAG, SI_TAG), OP_MOV_MR, ModRM(MOD_R, RS1, RM_SI)); // MOV RSI, RS1
    EMIT_ROM (REX(RS2_TAG,SI_TAG),OP_AND_MR,ModRM(MOD_R,RS2,RM_SI)); // AND RSI, RS2
    EMIT_ROM (REX(SI_TAG,RD_TAG), OP_MOV_MR, ModRM(MOD_R,R_SI,RD)); // MOV RD, RSI
    return tptr;
}

// uint
// emit_and (struct ins * inst) {
//     EMIT_ROM (REX(RS1_TAG, SI_TAG), OP_MOV_MR, ModRM(MOD_R, RS1, RM_SI)); // MOV RSI, RS1
//     EMIT_ROM (REX(RS2_TAG,SI_TAG),OP_AND_MR,ModRM(MOD_R,RS2,RM_SI)); // AND RSI, RS2
//     EMIT_ROM (REX(SI_TAG,RD_TAG), OP_MOV_MR, ModRM(MOD_R,R_SI,RD)); // MOV RD, RSI
// }

uint
emit_not (struct ins * inst) {
    EMIT_ROM (REX(RS1_TAG, SI_TAG), OP_MOV_MR, ModRM(MOD_R, RS1, RM_SI)); // MOV RSI, RS1
    EMIT_ROM (REX_W, OP_NOT_M,ModRM(MOD_R,2,RM_SI));  // NOT RSI
    EMIT_ROM (REX(SI_TAG,RD_TAG), OP_MOV_MR, ModRM(MOD_R,R_SI,RD)); // MOV RD, RSI
    return tptr;
}

uint
emit_ldi (struct ins * inst) {
    if (!(inst->v->flg & F_VAR_VALID))
        return ERROR;
    if (inst->v->flg & F_VAR_STACK) {
        EMIT_O(OP_PUSH_AX); // PUSH RAX
        EMIT_O(OP_PUSH_BX); // PUSH RBX
        EMIT_ROM (REX(RS1_TAG, SI_TAG), OP_MOV_MR, ModRM(MOD_R, RS1, RM_SI)); // MOV RSI, RS1
        EMIT_ROMI8 (REX_W, OP_SHL_MI8, ModRM(MOD_R,6,RM_SI),getvaridxshft(inst->addrmode)); // SHL RSI, varidxshft
        EMIT_ROI64 (REX_W, OP_MOVABS, V->stackoff); // MOVABS RAX, v->stackoff, FP+v->stackoff => 实际内容指针地址
        EMIT_ROMI8(REX_W, OP_MOV_RM, ModRM(MOD_RM_D8,R_BX,R_DI),96); // MOV RBX, 96[RDI] => FP
        EMIT_ROM(REX_W, OP_ADD_MR,ModRM(MOD_R,R_BX,RM_AX)); // ADD RAX, RBX RAX=FP+v->stackoff
        EMIT_ROM(REX_W, OP_MOV_RM, ModRM(MOD_RM,R_AX,RM_AX)); // MOV RAX, [RAX] # 指向实际内容的指针 => RAX
        EMIT_ROM(REX_W, OP_ADD_MR, ModRM(MOD_R,R_SI,RM_AX)); // ADD RAX, RSI
        switch (getvaridxshft(inst->addrmode)) {
            case 0: {
                if (issigned (V)) {
                    EMIT_RPOM (REX_W,PREFIX,OP_MOVSX_RM8,ModRM(MOD_RM,R_AX,RM_AX)); // MOVSB RAX, [RAX]
                } else {
                    EMIT_OM (OP_MOV_RM8, ModRM(MOD_RM,R_AX,RM_AX)); // MOVB AL, [RAX]
                }
                break;
            }
            case 1: {
                if (issigned (V)) {
                    EMIT_RPOM (REX_W,PREFIX,OP_MOVSX_RM16,ModRM(MOD_RM,R_AX,RM_AX)); // MOVSW RAX, [RAX]
                } else {
                    EMIT_ROM (REX_16, OP_MOV_RM,ModRM(MOD_RM,R_AX,RM_AX)); // MOVW AX, [RAX]
                }
                break;
            }
            case 2: {
                if (issigned (V)) {
                    EMIT_ROM (REX_W,OP_MOVSX_RM,ModRM(MOD_RM,R_AX,RM_AX)); // MOVSL RAX, [RAX]
                } else {
                    EMIT_OM (OP_MOV_MR,ModRM(MOD_RM,R_AX,RM_AX)); // MOVL EAX, [RAX]
                }
                break;
            }
            case 3: {
                EMIT_ROM (REX_W ,OP_MOV_RM,ModRM(MOD_RM,R_AX,RM_AX)); // MOVQ RAX, [RAX]
                break;
            }
        }
        EMIT_O (OP_POP_BX); // POP RBX
        EMIT_O (OP_POP_AX); // POP RAX
        return tptr;
    }
    if (inst->v->flg & F_VAR_HEAP) {
        EMIT_O(OP_PUSH_AX); // PUSH RAX
        EMIT_ROM (REX(RS1_TAG, SI_TAG), OP_MOV_MR, ModRM(MOD_R, RS1, RM_SI)); // MOV RSI, RS1
        EMIT_ROMI8 (REX_W, OP_SHL_MI8, ModRM(MOD_R,6,RM_SI),getvaridxshft(inst->addrmode)); // SHL RSI, varidxshft
        EMIT_ROI64 (REX_W, OP_MOVABS, (uint64)V->heapaddr); // MOVABS RAX, v->heapaddr, 存储指向实际内容的指针
        EMIT_ROM(REX_W, OP_MOV_RM, ModRM(MOD_RM,R_AX,RM_AX)); // MOV RAX, [RAX] # str或space的实际内容
        EMIT_ROM(REX_W, OP_ADD_MR, ModRM(MOD_R,R_SI,RM_AX)); // ADD RAX, RSI
        switch (getvaridxshft(inst->addrmode)) {
            case 0: {
                EMIT_OM (OP_MOV_RM8, ModRM(MOD_RM,R_AX,RM_AX)); // MOVB AL, [RAX]
                break;
            }
            case 1: {
                EMIT_ROM (REX_16, OP_MOV_RM,ModRM(MOD_RM,R_AX,RM_AX)); // MOVW AX, [RAX]
                break;
            }
            case 2: {
                EMIT_OM (OP_MOV_RM,ModRM(MOD_RM,R_AX,RM_AX)); // MOVL EAX, [RAX]
                break;
            }
            case 3: {
                EMIT_ROM (REX_W ,OP_MOV_RM,ModRM(MOD_RM,R_AX,RM_AX)); // MOVQ RAX, [RAX]
                break;
            }
        }
        EMIT_O (OP_POP_AX); // POP RAX
        return tptr;
    }
    return ERROR;
}

uint
emit_sti (struct ins * inst) {
    if (!(inst->v->flg & F_VAR_VALID))
        return ERROR;
    if (inst->v->flg & F_VAR_STACK) {
        EMIT_O(OP_PUSH_AX); // PUSH RAX
        EMIT_O(OP_PUSH_BX); // PUSH RBX
        EMIT_ROM (REX(RS1_TAG, SI_TAG), OP_MOV_MR, ModRM(MOD_R, RS1, RM_SI)); // MOV RSI, RS1
        EMIT_ROMI8 (REX_W, OP_SHL_MI8, ModRM(MOD_R,6,RM_SI),getvaridxshft(inst->addrmode)); // SHL RSI, varidxshft
        EMIT_ROI64 (REX_W, OP_MOVABS, V->stackoff); // MOVABS RAX, v->stackoff, FP+v->stackoff => 实际内容指针地址
        EMIT_ROMI8(REX_W, OP_MOV_RM, ModRM(MOD_RM_D8,R_BX,R_DI),96); // MOV RBX, 96[RDI] => FP
        EMIT_ROM(REX_W, OP_ADD_MR,ModRM(MOD_R,R_BX,RM_AX)); // ADD RAX, RBX RAX=FP+v->stackoff
        EMIT_ROM(REX_W, OP_MOV_RM, ModRM(MOD_RM,R_AX,RM_AX)); // MOV RAX, [RAX] # 指向实际内容的指针 => RAX
        EMIT_ROM(REX_W, OP_ADD_MR, ModRM(MOD_R,R_SI,RM_AX)); // ADD RAX, RSI
        switch (getvaridxshft(inst->addrmode)) {
            case 0: {
                EMIT_OM (OP_MOV_MR8, ModRM(MOD_RM,R_AX,RM_AX)); // MOVB [RAX], AL
                break;
            }
            case 1: {
                EMIT_ROM (REX_16, OP_MOV_MR,ModRM(MOD_RM,R_AX,RM_AX)); // MOVW [RAX], AX
                break;
            }
            case 2: {
                EMIT_OM (OP_MOV_MR,ModRM(MOD_RM,R_AX,RM_AX)); // MOVL [RAX], EAX
                break;
            }
            case 3: {
                EMIT_ROM (REX_W ,OP_MOV_MR,ModRM(MOD_RM,R_AX,RM_AX)); // MOVQ [RAX], RAX
                break;
            }
        }
        EMIT_O (OP_POP_BX); // POP RBX
        EMIT_O (OP_POP_AX); // POP RAX
        return tptr;
    }
    if (inst->v->flg & F_VAR_HEAP) {
        EMIT_O(OP_PUSH_AX); // PUSH RAX
        EMIT_ROM (REX(RS1_TAG, SI_TAG), OP_MOV_MR, ModRM(MOD_R, RS1, RM_SI)); // MOV RSI, RS1
        EMIT_ROMI8 (REX_W, OP_SHL_MI8, ModRM(MOD_R,6,RM_SI),getvaridxshft(inst->addrmode)); // SHL RSI, varidxshft
        EMIT_ROI64 (REX_W, OP_MOVABS, (uint64)V->heapaddr); // MOVABS RAX, v->heapaddr, 存储指向实际内容的指针
        EMIT_ROM(REX_W, OP_MOV_RM, ModRM(MOD_RM,R_AX,RM_AX)); // MOV RAX, [RAX] # str或space的实际内容
        EMIT_ROM(REX_W, OP_ADD_MR, ModRM(MOD_R,R_SI,RM_AX)); // ADD RAX, RSI
        switch (getvaridxshft(inst->addrmode)) {
            case 0: {
                EMIT_OM (OP_MOV_MR8, ModRM(MOD_RM,R_AX,RM_AX)); // MOVB [RAX], AL
                break;
            }
            case 1: {
                EMIT_ROM (REX_16, OP_MOV_MR,ModRM(MOD_RM,R_AX,RM_AX)); // MOVW [RAX], AX
                break;
            }
            case 2: {
                EMIT_OM (OP_MOV_MR,ModRM(MOD_RM,R_AX,RM_AX)); // MOVL [RAX], EAX
                break;
            }
            case 3: {
                EMIT_ROM (REX_W ,OP_MOV_MR,ModRM(MOD_RM,R_AX,RM_AX)); // MOVQ [RAX], RAX
                break;
            }
        }
        EMIT_O (OP_POP_AX); // POP RAX
        return tptr;
    }
    return ERROR;
}

uint
emit_ld (struct ins * inst) {
    if (!(inst->v->flg & F_VAR_VALID)) return ERROR;
    if ((inst->v->flg & F_VAR_STACK)) {
        //printf ("EMITING LD\n");
        EMIT_O(OP_PUSH_AX); // PUSH RAX
        EMIT_ROI64 (REX_W, OP_MOVABS, V->stackoff);
        EMIT_ROMI8(REX_W, OP_MOV_RM, ModRM(MOD_RM_D8,R_SI,R_DI),96);  // MOV RSI, 96[RDI] => FP
        EMIT_ROM(REX_W, OP_ADD_MR, ModRM(MOD_R,R_AX,RM_SI)); // ADD RSI, RAX 这个地方是栈中首地址, RSI是首地址
        EMIT_ROI64 (REX_W, OP_MOVABS, (uint64)&(V->type)); // EAX <- V->type
        // cmp [RAX], 7 => I64前
        EMIT_OMI8 (OP_CMP_MI8, ModRM(MOD_RM, 7, RM_AX), 7);
        // jb 0x3
        EMIT_OI8 (OP_JB_REL8, 5);
        EMIT_ROM (REX_W ,OP_MOV_RM,ModRM(MOD_RM,R_AX,RM_SI)); // MOVQ RAX, [RSI]
        EMIT_OI8 (OP_J_REL8,27) ; // <> // 2
        // cmp [RAX], 5 => I32前
        EMIT_OMI8 (OP_CMP_MI8, ModRM(MOD_RM, 7, RM_AX), 5); // 3
        // jb 0x3 
        EMIT_OI8 (OP_JB_REL8, 5); // 2
        EMIT_ROM (REX_W,OP_MOVSX_RM,ModRM(MOD_RM,R_AX,RM_SI)); // MOVSXD EAX, [RSI] // 3
        EMIT_OI8 (OP_J_REL8,17) ;  // <> // 2
        // cmp [RAX], 3 => I16前
        EMIT_OMI8 (OP_CMP_MI8, ModRM(MOD_RM, 7, RM_AX), 3); //3
        // jb 0x3
        EMIT_OI8 (OP_JB_REL8, 5); // <> // 2
        EMIT_ROM (REX_16, OP_MOV_RM,ModRM(MOD_RM,R_AX,RM_SI)); // MOVW AX, [RSI] //3
        EMIT_OI8 (OP_J_REL8,7) ;  // 2
        // cmp [RAX], 1 => I8前 (无效)
        EMIT_OMI8 (OP_CMP_MI8, ModRM(MOD_RM, 7, RM_AX), 1); // 3
        // jb 0x3
        EMIT_OI8 (OP_JB_REL8, 0x2); // 2
        EMIT_OM (OP_MOV_RM8, ModRM(MOD_RM,R_AX,RM_SI)); // MOVB AL, [RSI] 2
        EMIT_ROM (REX(RD_TAG, AX_TAG), OP_MOV_MR, ModRM(MOD_R, R_AX, RD)); // MOV RD, RAX
        EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R, R_SI, R_AX)); // MOV RAX, RSI
        EMIT_O(OP_POP_AX); // POP RAX
        return tptr;
    }
    if ((inst->v->flg & F_VAR_HEAP)) { // 有BUG,需要检查
        EMIT_O(OP_PUSH_AX); // PUSH RAX
        EMIT_ROI64 (REX_W, OP_MOVABS, (uint64)V->heapaddr); // MOVABS RAX, v->heapaddr, 存储指向实际内容的指针
        EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R, R_AX, R_SI)); // MOV RSI, RAX
        EMIT_ROI64 (REX_W, OP_MOVABS, (uint64)&(V->type)); // EAX <- V->type
        // cmp [RAX], 7 => I64前
        EMIT_OMI8 (OP_CMP_MI8, ModRM(MOD_RM, 7, RM_AX), 7);
        // jb 0x3
        EMIT_OI8 (OP_JB_REL8, 5);
        EMIT_ROM (REX_W ,OP_MOV_RM,ModRM(MOD_RM,R_AX,RM_SI)); // MOVQ RAX, [RSI]
        EMIT_OI8 (OP_J_REL8,26) ; // <> // 2
        // cmp [RAX], 5 => I32前
        EMIT_OMI8 (OP_CMP_MI8, ModRM(MOD_RM, 7, RM_AX), 5); // 3
        // jb 0x3 
        EMIT_OI8 (OP_JB_REL8, 4); // 2
        EMIT_OM (OP_MOV_RM,ModRM(MOD_RM,R_AX,RM_SI)); // MOVL EAX, [RSI] // 2
        EMIT_OI8 (OP_J_REL8,17) ;  // <> // 2
        // cmp [RAX], 3 => I16前
        EMIT_OMI8 (OP_CMP_MI8, ModRM(MOD_RM, 7, RM_AX), 3); //3
        // jb 0x3
        EMIT_OI8 (OP_JB_REL8, 5); // <> // 2
        EMIT_ROM (REX_16, OP_MOV_RM,ModRM(MOD_RM,R_AX,RM_SI)); // MOVW AX, [RSI] //3
        EMIT_OI8 (OP_J_REL8,7) ;  // 2
        // cmp [RAX], 1 => I8前 (无效)
        EMIT_OMI8 (OP_CMP_MI8, ModRM(MOD_RM, 7, RM_AX), 1); // 3
        // jb 0x3
        EMIT_OI8 (OP_JB_REL8, 0x2); // 2
        EMIT_OM (OP_MOV_RM8, ModRM(MOD_RM,R_AX,RM_SI)); // MOVB AL, [RSI] 2
        EMIT_ROM (REX(RD_TAG, AX_TAG), OP_MOV_MR, ModRM(MOD_R, R_AX, RD)); // MOV RD, RAX
        EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R, R_SI, R_AX)); // MOV RAX, RSI
        EMIT_O(OP_POP_AX); // POP RAX
        return tptr;
    }
    return ERROR;
}

uint
emit_st (struct ins * inst) {
    if (!(inst->v->flg & F_VAR_VALID)) return ERROR;
    if ((inst->v->flg & F_VAR_STACK)) {
        EMIT_O(OP_PUSH_AX); // PUSH RAX
        // EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R, R_AX, RM_SI)); //MOV RSI, RAX
        EMIT_ROI64 (REX_W, OP_MOVABS, V->stackoff);
        EMIT_ROMI8(REX_W, OP_MOV_RM, ModRM(MOD_RM_D8,R_SI,R_DI),96);  // MOV RSI, 96[RDI] => FP
        EMIT_ROM(REX_W, OP_ADD_MR, ModRM(MOD_R,R_SI,RM_AX)); // ADD RAX, RSI 这个地方是栈中首地址
        switch (getvaridxshft(V->type)) {
            case 0: {
                EMIT_OM (OP_MOV_MR8, ModRM(MOD_RM,R_AX,RM_AX)); // MOVB [RAX], AL
                break;
            }
            case 1: {
                EMIT_ROM (REX_16, OP_MOV_MR,ModRM(MOD_RM,R_AX,RM_AX)); // MOVW [RAX], AX 
                break;
            }
            case 2: {
                EMIT_OM (OP_MOV_MR,ModRM(MOD_RM,R_AX,RM_AX)); // MOVL [RAX], EAX 
                break;
            }
            case 3: {
                EMIT_ROM (REX_W ,OP_MOV_MR,ModRM(MOD_RM,R_AX,RM_AX)); // MOVQ [RAX], RAX 
                break;
            }
        }
        EMIT_ROM (REX(RD_TAG, AX_TAG), OP_MOV_MR, ModRM(MOD_R, R_AX, RD)); // MOV RD, RAX
        EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R, R_SI, R_AX)); // MOV RAX, RSI
        EMIT_O(OP_POP_AX); // POP RAX
        return tptr;
    }
    if ((inst->v->flg & F_VAR_HEAP)) {
        EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R, R_AX, RM_SI)); //MOV RSI, RAX
        EMIT_ROI64 (REX_W, OP_MOVABS, (uint64)V->heapaddr); // MOVABS RAX, v->heapaddr, 存储指向实际内容的指针
        switch (getvaridxshft(V->type)) {
            case 0: {
                EMIT_OM (OP_MOV_MR8, ModRM(MOD_RM,R_AX,RM_AX)); // MOVB [RAX], AL 
                break;
            }
            case 1: {
                EMIT_ROM (REX_16, OP_MOV_MR,ModRM(MOD_RM,R_AX,RM_AX)); // MOVW [RAX], AX 
                break;
            }
            case 2: {
                EMIT_OM (OP_MOV_MR,ModRM(MOD_RM,R_AX,RM_AX)); // MOVL [RAX], EAX 
                break;
            }
            case 3: {
                EMIT_ROM (REX_W ,OP_MOV_MR,ModRM(MOD_RM,R_AX,RM_AX)); // MOVQ [RAX], RAX 
                break;
            }
        }
        EMIT_ROM (REX(RD_TAG, AX_TAG), OP_MOV_MR, ModRM(MOD_R, R_AX, RD)); // MOV RD, RAX
        EMIT_ROM (REX_W, OP_MOV_MR, ModRM(MOD_R, R_SI, R_AX)); // MOV RAX, RSI
        return tptr;
        return tptr;
    }
    return ERROR;
}

uint emit_mv (struct ins * inst) {
    EMIT_ROM (REX(RS1_TAG, RD_TAG), OP_MOV_MR, ModRM (MOD_R, RS1, RD)); // MOV RD, RS1
    return tptr;
}

static uint (*emitfuncs[]) (struct ins *) = {
    [INS_ASGN]  emit_asgn,
    [INS_CAST]  emit_cast,
    [INS_LI]    emit_li,
    [INS_ADDI]  emit_addi,
    [INS_SLTI]  emit_slti,
    [INS_SLTIU] emit_sltiu,
    [INS_XORI]  emit_xori,
    [INS_ORI]   emit_ori,
    [INS_ANDI]  emit_andi,
    [INS_SLLI]  emit_slli,
    [INS_SRLI]  emit_srli,
    [INS_SRAI]  emit_srai,
    [INS_ADD]   emit_add,
    [INS_SUB]   emit_sub,
    [INS_SLL]   emit_sll,
    [INS_SLT]   emit_slt,
    [INS_SLTU]  emit_sltu,
    [INS_XOR]   emit_xor,
    [INS_SRL]   emit_srl,
    [INS_SRA]   emit_sra,
    [INS_OR]    emit_or,
    [INS_AND]   emit_and,
    [INS_NOT]   emit_not,
    [INS_LDI]   emit_ldi,
    [INS_STI]   emit_sti,
    [INS_LD]    emit_ld,
    [INS_ST]    emit_st,
    [INS_MV]    emit_mv,
    [INS_ECALL] emit_ecall
};

struct jitngin *
getjit (struct textseg * ts, struct sxbh * sh) {
    struct jitngin * jit;
    jit = (struct jitngin *) malloc (sizeof (struct jitngin));
    if (jit == NULL) return NULL;
    bzero (jit, sizeof (struct jitngin));
    jit->ts = ts;
    jit->xallocator = sh;
    return jit;
}

struct transblock *
genjitblk (struct jitngin * jit, uint addr) {
    uint64 pc;
    struct transblock * tb;
    tb = (struct transblock *) malloc (sizeof (struct transblock));
    if (tb == NULL) goto error;
    int icnt = 0;
    tptr = 0;
    struct ins * insp =  jit->ts->insls;
    #define JITCC_OK(ins) ((ins)->type>=INS_CAST&&(ins)->type<=INS_MV) // 可编译指令
    #define INST_OK(ins) (((ins)->flg & F_INS_VALID) && \
                        !(((ins)->flg & F_INS_RTC)&&(ins)->rtc ==RTC_RT))  // 指令有效且rtc不为RT
    #define I (insp+pc)
    pc=addr;
    if (!JITCC_OK(I) || !INST_OK(I)) goto error;
    emit_prologue (); // 生成函数序言
    for (pc=addr;pc < jit->ts->sz;pc++) {
        if (!JITCC_OK(I) || !INST_OK(I)) {
            goto finish;
        }
        emitfuncs[I->type](I);
        icnt++;
    }
    finish:
    if (icnt == 0) goto error;
    tb->inum = icnt; // 更新指令条数
    emit_epilogue (); // 生成函数尾声
    void * xblock = xalloc (jit->xallocator, tptr);
    if (xblock == NULL) goto error;
    memcpy (xblock, tbbuf, tptr);
    tb->exec = xblock;
    // success:
    return tb;
    error:
    free (tb);
    return NULL;
}

/* 在下一跳转标签前返回,同时更新PC*/
/* 待修复BUG:若目标寄存器在指令执行时被更改,则不需要恢复之前保存的值 */
int
jitexec (uint64 * regs, struct ins *  inst) {
    if (!(inst->flg & F_INS_TB) || !(inst->flg & F_INS_VALID))
        return ERROR;
    do_jitexec (regs, inst->tb->exec);
    regs[X_PC] += inst->tb->inum;
    return SUCCESS;
}